/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package servlet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import service.MumuUser;
import service.MumuUserFacadeREST;
import service.Universe;
import service.UniverseFacadeREST;
import session.UserData;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FilenameFilter;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.filechooser.FileFilter;
import jsonHelper.SimplePlanet;
import jsonHelper.SimpleUniverse;
import org.apache.commons.io.filefilter.FileFileFilter;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import service.Photo;
import service.PhotoCollection;
import service.Planet;
import utilities.AvatarGenerator;

/**
 *
 * @author andrew
 */
@WebServlet(name = "firstStepServlet", urlPatterns = {"/firstStepServlet"})
public class firstStepServlet extends HttpServlet {

    @EJB
    private UniverseFacadeREST universeManager;
    @EJB
    private MumuUserFacadeREST userManager;

    // <editor-fold desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP
     * <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //HttpSession session = request.getSession();
        // check if session is expired
        HttpSession session = request.getSession();// don't create if it doesn't exist


        String editingUniverseIdString = request.getParameter("editingUniverseId");

        int editingUniverseId;



        if (editingUniverseIdString == null) {
            // form vuote si crea un nuovo universo

            editingUniverseId = -1;
            session.setAttribute("nameUniverse", "");
            session.setAttribute("descriptionUniverse", "");
        } else {
            // form popolate perché si modifica un universo
            editingUniverseId = Integer.parseInt(editingUniverseIdString);



            Universe universe = universeManager.find(editingUniverseId);

            // creo le strighe dei path che mi servono
            ArrayList<BufferedImage> universeImages = new ArrayList<BufferedImage>();
            String rootPath = request.getServletContext().getRealPath("/") + "Universes/";
            String avatarPath = rootPath + editingUniverseIdString + "/";



            Collection<Planet> planets = universe.getPlanetCollection();
            Iterator<Planet> planetsIt = planets.iterator();
            Planet currentPlanet;
            File currentImage;
            while (planetsIt.hasNext()) {
                currentPlanet = planetsIt.next();
                Iterator<PhotoCollection> photoCollIt = currentPlanet.getPhotoCollectionCollection().iterator();
                PhotoCollection currentPhotoColl;
                while (photoCollIt.hasNext()) {
                    currentPhotoColl = photoCollIt.next();
                    Iterator<Photo> photoIt = currentPhotoColl.getPhotoCollection().iterator();
                    Photo currentPhoto;
                    while (photoIt.hasNext()) {
                        currentPhoto = photoIt.next();
                        System.out.println("Immagine: " + rootPath + currentPhoto.getPathPhoto());
                        currentImage = new File(rootPath + currentPhoto.getPathPhoto());
                        if (currentImage.exists()) {
                            universeImages.add(ImageIO.read(currentImage));
                        }
                    }
                }

            }

            if (universeImages.size() > 2) {
                boolean regeneration = true;
                File f = new File(avatarPath);
                String[] files = f.list(new FilenameFilter() {
                    @Override
                    public boolean accept(File dir, String name) {
                        return name.startsWith("avatar-");
                    }
                });

                if (files.length > 0) {
                    files[0] = files[0].replace("avatar-", "");
                    files[0] = files[0].replace(".png", "");
                    if (!files[0].equals("")) {
                        int currentAvatarId = Integer.parseInt(files[0]);
                        System.out.println(universeImages.size() + " ==? " + currentAvatarId);
                        if (universeImages.size() == currentAvatarId) {
                            regeneration = false;
                        }
                    }
                }

                if (regeneration) { // genera il nuovo array
                    Collections.shuffle(universeImages); // mescolo l'arraylist per dare un risultato diverso ogni volta

                    int oldSize = universeImages.size();

                    if (universeImages.size() > 8) {
                        universeImages.subList(8, universeImages.size()).clear();
                    }

                    AvatarGenerator ag = new AvatarGenerator(avatarPath, universeImages, oldSize);
                    BufferedImage currentAvatar = ImageIO.read(new File(avatarPath +"avatar-" + oldSize +".png"));
                    ImageIO.write(currentAvatar, "png", new File(rootPath + "avatar/" + editingUniverseIdString +".png"));
                    System.out.println("Path AG");
                    ArrayList<SimpleUniverse> oldList = (ArrayList<SimpleUniverse>) session.getAttribute("universeList");

                    Iterator<SimpleUniverse> simpleUniverseIt = oldList.iterator();
                    SimpleUniverse editingUniverse = null;
                    while (simpleUniverseIt.hasNext()) {
                        editingUniverse = simpleUniverseIt.next();
                        if (editingUniverse.getIdUniverse() == editingUniverseId) {
                            break;
                        }
                    }
                    editingUniverse.setAvatarPath("Universes/" + editingUniverseIdString + "/avatar-" + oldSize + ".png");

                }

            }



            session.setAttribute("nameUniverse", universe.getName());
            session.setAttribute("descriptionUniverse", universe.getDescription());
        }
        session.setAttribute("idUniverse", editingUniverseId);
        response.sendRedirect("/maker1.jsp");
    }

    /**
     * Handles the HTTP
     * <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // check if session is expired
        HttpSession session = request.getSession();// don't create if it doesn't exist
//        if(session != null && !session.isNew()) {} 
//        else {
//            response.sendRedirect("/home.jsp");
//        }

        String refUniverseFolder = "Universes/";

        //HttpSession session = request.getSession();
        String nameUniverse = request.getParameter("n");

        // tolgo spazi da name universe
        nameUniverse = nameUniverse.replaceAll("\\s", "");

        String descUniverse = request.getParameter("d");
        System.out.println("nameUniverse: " + nameUniverse);
        System.out.println("descUniverse: " + descUniverse);
        UserData userData = (UserData) session.getAttribute("userData");

        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();

        Gson gson = new Gson();
        JsonObject myObj = new JsonObject();

        JSONArray json = new JSONArray();

        Integer editingUniverseId = (Integer) session.getAttribute("idUniverse");

        if (isUniqueName(nameUniverse, editingUniverseId)) {

            if (editingUniverseId == -1) {

                // controllo se nome universo è univoco


                // creare una nuova entity e inserire in db
                Universe universe = new Universe();
                universe.setName(nameUniverse);
                universe.setDescription(descUniverse);
                universe.setIsValidated(false);
                universe.setIsReady(0);

                MumuUser utente;

                utente = userManager.find(userData.getIDUser());
                System.out.print("utente = " + utente.getNameSurname());
                Collection<Universe> collUniverse = utente.getUniverseCollection();
                //            
                //            collUniverse.add(universe);
                //            //System.out.print("coll = "+collUniverse.size());
                //            utente.setUniverseCollection(collUniverse);
                //            userManager.edit(utente);



                Collection<MumuUser> collUser = new ArrayList<MumuUser>();// universe.getMumuUserCollection();
                collUser.add(utente);
                universe.setMumuUserCollection(collUser);
                universeManager.edit(universe);


                //Universe universe = universeManager.find(editingUniverseId);
                Collection<SimplePlanet> arraySimplePlanet = new ArrayList<SimplePlanet>();

                //String temp = new String(); 
                collUniverse = universeManager.findAll();

                int newIdUniverse = -1;

                Iterator iterator = collUniverse.iterator();
                Universe u = null;
                while (iterator.hasNext()) {
                    u = (Universe) iterator.next();
                    if (u.getDescription().equals(descUniverse)) {
                        newIdUniverse = u.getIdUniverse();
                        break;
                    }
                }

                if (u != null) {
                    int validated = u.getIsValidated() ? 1 : 0;
                    SimpleUniverse newUniverse = new SimpleUniverse(u.getIdUniverse(), u.getName(), u.getDescription(), "img/no-avatar.png", u.getIsReady(), validated);
                    ArrayList<SimpleUniverse> oldList = (ArrayList<SimpleUniverse>) session.getAttribute("universeList");
                    oldList.add(newUniverse);
                    session.setAttribute("univeseList", oldList);
                } else {
                    System.out.println("UNIVERSO CREATO è NULL");
                }

                SimplePlanet s = new SimplePlanet(newIdUniverse, "", "", "", "", "");

                arraySimplePlanet.add(s);

                System.out.print("newIdUniverse = " + newIdUniverse);
                //trascrizione in SimplePlanet per inviare in JSON i pianeti associati a uno specifico universo
                session.setAttribute("idUniverse", newIdUniverse);

                String arrayGson = gson.toJson(arraySimplePlanet);

                // restituzione JSON
                out.println(arrayGson);
                out.close();

                // creazione cartella universo
                Boolean success = (new File(request.getServletContext().getRealPath("/") + refUniverseFolder + newIdUniverse)).mkdirs();
                if (!success) {
                    // creazione directory fallita
                }

                // creazione cartella immagini-universo
                success = (new File(request.getServletContext().getRealPath("/") + refUniverseFolder + newIdUniverse + "/" + "image")).mkdirs();
                if (!success) {
                    // creazione directory fallita
                }

                // creazione cartella video-universo
                success = (new File(request.getServletContext().getRealPath("/") + refUniverseFolder + newIdUniverse + "/" + "video")).mkdirs();
                if (!success) {
                    // creazione directory fallita
                }

                // creazione cartella audio-universo
                success = (new File(request.getServletContext().getRealPath("/") + refUniverseFolder + newIdUniverse + "/" + "audio")).mkdirs();
                if (!success) {
                    // creazione directory fallita
                }


            } else {

                // si fa edit di una entity esistente              
                Universe universe = universeManager.find(editingUniverseId);
                universe.setName(nameUniverse);
                universe.setDescription(descUniverse);
                universeManager.edit(universe);

                // ritorna la lista dei pianeti associati e li mette in Json

                //Universe universe = universeManager.find(editingUniverseId);
                Collection<Planet> collPlanet = universe.getPlanetCollection();

                ArrayList<SimplePlanet> arraySimplePlanet = new ArrayList<SimplePlanet>();
                arraySimplePlanet.add(new SimplePlanet(editingUniverseId, "", "", "", "", "")); // glitch per inviare il nome universo, da togliere!

                ArrayList<SimpleUniverse> oldList = (ArrayList<SimpleUniverse>) session.getAttribute("universeList");

                Iterator<SimpleUniverse> simpleUniverseIt = oldList.iterator();
                SimpleUniverse editingUniverse = null;
                while (simpleUniverseIt.hasNext()) {
                    editingUniverse = simpleUniverseIt.next();
                    if (editingUniverse.getIdUniverse() == editingUniverseId) {
                        break;
                    }
                }
                if (editingUniverse != null) {
                    editingUniverse.setNameUniverse(nameUniverse);
                    editingUniverse.setDescriptionUniverse(descUniverse);
                }
                //trascrizione in SimplePlanet per inviare in JSON i pianeti associati a uno specifico universo
                Iterator iterator = collPlanet.iterator();
                System.out.println("-----");
                while (iterator.hasNext()) {

                    Planet element = (Planet) iterator.next();

                    System.out.println("pianeta: " + element.getTitle1());
                    SimplePlanet simplePlanet = new SimplePlanet();

                    simplePlanet.setIdPlanet(element.getIdPlanet());
                    simplePlanet.setReferenceName(element.getReferenceName());
                    simplePlanet.setShortLabel(element.getShortLabel());
                    simplePlanet.setX(element.getCoordinatePositionX());
                    simplePlanet.setY(element.getCoordinatePositionY());
                    simplePlanet.setTitolo1(element.getTitle1());
                    simplePlanet.setTitolo2(element.getTitle2());
                    simplePlanet.setTitolo3(element.getTitle3());

                    arraySimplePlanet.add(simplePlanet);
                }
                System.out.println("-----");
                String arrayGson = gson.toJson(arraySimplePlanet);

                // restituzione JSON
                out.println(arrayGson);
                out.close();

            }


        } else {
            // esiste già un nome uguale
            try {
                // ritorno errore perchè il nome universo esiste già
                JSONObject jsonerror = new JSONObject();
                jsonerror.put("error", "L'universo con nome " + nameUniverse + " esiste gi&agrave;!!!");
                response.getWriter().write(jsonerror.toString());
                System.out.println("Stringa in JSON: " + jsonerror.toString());
                response.getWriter().close();
            } catch (JSONException ex) {
                Logger.getLogger(firstStepServlet.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

    private boolean isUniqueName(String name, int editingId) {

        List<Universe> universeList = universeManager.findAll();
        Iterator<Universe> universeIt = universeList.iterator();
        Universe universe;
        String universeNameUpperCase = "";
        String nameUpperCase = "";
        while (universeIt.hasNext()) {
            universe = universeIt.next();
            
            universeNameUpperCase = universe.getName().toUpperCase();
            nameUpperCase = name.toUpperCase();
            
            if (universeNameUpperCase.equals(nameUpperCase) && (editingId == -1 || editingId != universe.getIdUniverse())) {
                return false;
            }
        }

        return true;

    }
}
